package edu.towson.cis.cosc603.project4.vendingmachine;

import static org.junit.Assert.*;

import org.junit.*;

public class VendingMachineTEST {
        // The number of slots in the vending machine
        public static final int NUM_SLOTS = 4;

        // The code for the "A" slot
        public static final String A_CODE = "A";

        // The code for the "B" slot
        public static final String B_CODE = "B";
        
        // The code for the "C" slot
        public static final String C_CODE = "C";
         
        // The code for the "D" slot
        public static final String D_CODE = "D";
        
        VendingMachine vm;
        VendingMachineItem vmitem1;
        VendingMachineItem vmitem2;
        VendingMachineItem vmitem3;
        VendingMachineItem vmitem4;
        
        /**
         * @throws java.lang.Exception
         */
        @BeforeClass
        public static void setUpBeforeClass() throws Exception {
        }

        /**
         * @throws java.lang.Exception
         */
        @AfterClass
        public static void tearDownAfterClass() throws Exception {
        }

        /**
         * @throws java.lang.Exception
         */
        @Before
        public void setUp() throws Exception {
        	
                vm = new VendingMachine();
                vmitem1 = new VendingMachineItem("KitKat", 1.0);
                vmitem2 = new VendingMachineItem("Oreo", 1);
                vmitem3 = new VendingMachineItem("Lays", 1);
                vmitem4 = new VendingMachineItem("Snyder's", 2);
        }
        
        @Test
        public void testVendingMachine(){
        	
                assertEquals(null, vm.getItem("A")); //For testing whether array is null or not.
                assertEquals(null, vm.getItem("B")); 
                assertEquals(null, vm.getItem("C")); 
                assertEquals(null, vm.getItem("D")); 
                assertEquals(0, vm.getBalance() , 0); //For testing whether balance is '0' or not
                
        }
        
        @Test 
        public void testAddItem(){
        	
                vm.addItem(vmitem1, "A"); //Add item to slot.            
                vm.addItem(vmitem2, "B");
                vm.addItem(vmitem3, "C");
                vm.addItem(vmitem4, "D");
                
                VendingMachineItem item1 = vm.getItem("A");
                VendingMachineItem item2 = vm.getItem("B");
                VendingMachineItem item3 = vm.getItem("C");
                VendingMachineItem item4 = vm.getItem("D");
                
                assertEquals("KitKat", item1.getName()); //For testing difference between the name of array and the name of inserted item.
                assertEquals("Oreo", item2.getName()); 
                assertEquals("Lays", item3.getName());
                assertEquals("Snyder's", item4.getName());
                
                assertEquals(1.0, item1.getPrice(), 0); //For testing difference between the price of array and the price of inserted item
                assertEquals(1, item2.getPrice(), 0);
                assertEquals(1, item3.getPrice(), 0);
                assertEquals(2, item4.getPrice(), 0);
        }
        
        @Test 
        public void testAddItemException(){
                vm.addItem(vmitem1, "A");               
                vm.addItem(vmitem1, "A"); //For testing this program handle exception for using same slot again. 
        }
        
        @Test
        public void testRemoveItem(){
                vm.addItem(vmitem1, "A");
                VendingMachineItem item = vm.removeItem("A");
                
                assertEquals("KitKat", item.getName()); //For testing difference between the name of return value and the name of expected value.
                assertEquals(1.0, item.getPrice(), 0); //For testing difference between the price of return value and the price of expected value.
                
                assertEquals(null, vm.getItem("A")); //For testing whether 'A' is removed or not.
        }
        
        @Test 
        public void testRemoveItemException(){
                VendingMachineItem vmitem1 = vm.removeItem("A");  //For testing this program handle exception for remove item from empty slot.
        }
        
        
        @Test
        public void testInsertMoney(){
                vm.insertMoney(1.0);
                vm.insertMoney(1);
                assertEquals(3, vm.getBalance(), 0); //For testing when user has enough money to buy items.
        }
        
        @Test 
        public void testInsertMoneyException(){
                vm.insertMoney(-1); //For testing this program handle exception for negative balance is inserted.
        }
        
        @Test
        public void testGetBalance(){
                vm.insertMoney(2.5);
                assertEquals(2.5, vm.getBalance(), 0); //For testing difference between the price of return value and the price of expected value
                
                vm.addItem(vmitem1, "A");
                vm.makePurchase("A");
                assertEquals(1, vm.getBalance(), 0); //For testing the balance after makePurchase().
        }
        
        @Test
        public void testMakePurchase(){
                vm.addItem(vmitem3, "C");
                vm.addItem(vmitem4, "D");  
                
                vm.insertMoney(2);
                
                assertEquals(true, vm.makePurchase("C")); //For testing the return value is true when item != null and balance >= price
                assertEquals(false, vm.makePurchase("D")); //For testing the return value is false when item == null and balance >= price
           }
        
        @Test
        public void testReturnChange(){
                vm.insertMoney(3.0);
                
                assertEquals(3.0, vm.returnChange(), 0); //For testing return value of returnChange() is correct or not.

                vm.addItem(vmitem4, "D");
                vm.insertMoney(1.0);
                vm.makePurchase("A");
                
                assertEquals(2, vm.returnChange(), 0); //For testing return value of returnChange() is correct or not after makePurchase()
        }

        /**
         * @throws java.lang.Exception
         */
        @After
        public void tearDown() throws Exception {
        }

        
        
}